// a5a5a5a5a5a5a5a5feff
// 00800000000000005402
// 3400a30601000000012b000000000000100010000000020a0000000001010100021410000000cedec8cbd6b5cad8b3c6d6d8cfb5cdb3cb965a
// a5 a5 a5 a5 a5 a5 a5 a5 fe ff
// 00 80 00 00 00 00 00 00 54 02 
// 34 //DataLen
// 00 a3 06 01 00 00 00 01 
// 2b //AreaDataLen0
// 00 00 00 00 
// 00 // AreaY 0
// 00 10 00 10 00 
// 00 //DynamicAreaLoc
// 00 02 0a 00 00 00 00 01 01 01 00 02 14 
// 10 //DataLen
// 00 00 00
// ce de c8 cb d6 b5 ca d8 b3 c6 d6 d8 cf b5 cd b3 // 无人值守称重系统
// cb 96 
// 5a                      
// a5a5a5a5a5a5a5a5feff008000000000000054023100a306010000000128000000001000100010000100020a000000000101010002140d000000b3b5bac53abea9414231323334f0085a                                                
// a5a5a5a5a5a5a5a5feff008000000000000054023100a306010000000128000000001000100010000100020a000000000101010002140d000000b3b5bac53abea9414231323334f0085a
// a5 a5 a5 a5 a5 a5 a5 a5 fe ff
// 00 80 00 00 00 00 00 00 54 02 
// 31 //DataLen
// 00 a3 06 01 00 00 00 01 
// 28 //AreaDataLen0
// 00 00 00 00 
// 10 // AreaY 16
// 00 10 00 10 00 
// 01 // DynamicAreaLoc
// 00 02 0a 00 00 00 00 01 01 01 00 02 14 
// 0d //DataLen
// 00 00 00
// b3 b5 ba c5 3a be a9 41 42 31 32 33 34 // 车号:京AB1234
// c3 3b 
// 5a

// feff008000000000000054022700a306010000000121000000003000100010000300020a0000000001010100021406000000c7ebcfc2b0f5
// a5 a5 a5 a5 a5 a5 a5 a5 fe ff
// 00 80 00 00 00 00 00 00 54 02
// 2a //DataLen
// 00 a3 06 01 00 00 00 01
// 21 //AreaDataLen0
// 00 00 00 00
// 30 // AreaY 48
// 00 10 00 10 00
// 03 // DynamicAreaLoc
// 00 02 0a 00 00 00 00 01 01 01 00 02 14
// 06 //DataLen
// 00 00 00
// c7 eb cf c2 b0 f5 // 请下磅
// e8 67
// 5a
import {Socket} from "net";
import {EventEmitter, iconv} from "../node-test";
import log from "./logger";
import utils from "./utils";
import {Led} from "./interfaces";
import settings from "./settings";

class LedImpl extends EventEmitter implements Led {
    socket1: Socket
    socket2: Socket
    port = 5005
    hostname1 = ''
    hostname2 = ''

    public constructor() {
        super();
    }

    get(text: string, line: 1 | 2 | 3 | 4) {
        const textbuf = iconv.encode(text, 'GB2312')

        const frameheader = [0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5]
        const buf1 = [0xfe, 0xff]
        const buf2 = [0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02]
        const buf3 = [42 - 6 + textbuf.length] //DataLen
        const buf4 = [0x00, 0xa3, 0x06, 0x01, 0x00, 0x00, 0x00, 0x01]
        const buf5 = [33 - 6 + textbuf.length] //AreaDataLen0
        const buf6 = [0x00, 0x00, 0x00, 0x00]
        const buf7 = [(line - 1) * 16] // AreaY 48
        const buf8 = [0x00, 0x10, 0x00, 0x10, 0x00]
        const buf9 = [line - 1] // DynamicAreaLoc
        const buf10 = [0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x14]
        const buf11 = [textbuf.length]
        const buf12 = [0x00, 0x00, 0x00]
        // const buf13 = [0xc7, 0xeb, 0xcf, 0xc2, 0xb0, 0xf5]
        const buf13 = []
        for (let i = 0; i < textbuf.length; i++) {
            buf13.push(textbuf[i])
        }
        const pack = buf1.concat(buf2).concat(buf3).concat(buf4).concat(buf5).concat(buf6).concat(buf7)
            .concat(buf8).concat(buf9).concat(buf10).concat(buf11).concat(buf12).concat(buf13)
        let packStr = pack.map((value) => {
            return (value.toString(16).length === 1 ? '0' : '') + value.toString(16)
        }).join('')
        const crcStr = utils.crc(packStr)
        const buf14 = [parseInt(crcStr.substr(2, 2), 16), parseInt(crcStr.substr(0, 2), 16)]
        const framefooter = [0x5a]

        const escapebefore = pack.concat(buf14)
        const escapeafter: number[] = []
        escapebefore.forEach((value) => {
            if (value === 0xa5) {
                escapeafter.push(0xa6)
                escapeafter.push(0x02)
            } else if (value === 0xa6) {
                escapeafter.push(0xa6)
                escapeafter.push(0x01)
            } else if (value === 0x5a) {
                escapeafter.push(0x5b)
                escapeafter.push(0x02)
            } else if (value === 0x5b) {
                escapeafter.push(0x5b)
                escapeafter.push(0x01)
            } else {
                escapeafter.push(value)
            }
        })

        return new Uint8Array(
            frameheader.concat(escapeafter).concat(framefooter)
        )
        // a5 a5 a5 a5 a5 a5 a5 a5 fe ff
        // 00 80 00 00 00 00 00 00 54 02
        // 2a //DataLen
        // 00 a3 06 01 00 00 00 01
        // 21 //AreaDataLen0
        // 00 00 00 00
        // 30 // AreaY 48
        // 00 10 00 10 00
        // 03 // DynamicAreaLoc
        // 00 02 0a 00 00 00 00 01 01 01 00 02 14
        // 06 //DataLen
        // 00 00 00
        // c7 eb cf c2 b0 f5 // 请下磅
        // e8 67
        // 5a
    }

    async sendHlsk() {
        let linedata
        if (this.socket1) {
            linedata = this.get("无人值守称重系统", 1)
            this.socket1.write(linedata)
            await utils.sleep(200)
            linedata = this.get('互链时空', 2)
            this.socket1.write(linedata)
            await utils.sleep(200)
            linedata = this.get("请减速慢行", 3)
            this.socket1.write(linedata)
            await utils.sleep(200)
            linedata = this.get("注意车辆", 4)
            this.socket1.write(linedata)
        }

        if (this.socket2) {
            linedata = this.get("无人值守称重系统", 1)
            this.socket2.write(linedata)
            await utils.sleep(200)
            linedata = this.get('互链时空', 2)
            this.socket2.write(linedata)
            await utils.sleep(200)
            linedata = this.get("请减速慢行", 3)
            this.socket2.write(linedata)
            await utils.sleep(200);
            linedata = this.get("注意车辆", 4)
            this.socket2.write(linedata)
        }
    }

    async send(vehicle: string, weight: number) {
        let linedata
        if (this.socket1) {
            linedata = this.get("无人值守称重系统", 1)
            this.socket1.write(linedata)
            await utils.sleep(200)
            linedata = this.get('车号:' + vehicle, 2)
            this.socket1.write(linedata)
            await utils.sleep(200)
            linedata = this.get("过磅成功" + settings.isSayWeight ? ',' + weight + '吨' : '', 3)
            this.socket1.write(linedata)
            await utils.sleep(200)
            linedata = this.get("请下磅", 4)
            this.socket1.write(linedata)
        }

        if (this.socket2) {
            linedata = this.get("无人值守称重系统", 1)
            this.socket2.write(linedata)
            await utils.sleep(200)
            linedata = this.get('车号:' + vehicle, 2)
            this.socket2.write(linedata)
            await utils.sleep(200)
            linedata = this.get("过磅成功" + settings.isSayWeight ? ',' + weight + '吨' : '', 3)
            this.socket2.write(linedata)
            await utils.sleep(200)
            linedata = this.get("请下磅", 4)
            this.socket2.write(linedata)
        }
    }

    init() {
        this.hostname1 = settings.led1
        this.hostname2 = settings.led2
        log.info('led1 address:', this.hostname1)
        log.info('led2 address:', this.hostname2)

        if (settings.led1 !== '') {
            this.socket1 = new Socket();
            this.socket1.setEncoding('utf8');

            this.socket1.connect(this.port, this.hostname1);

            this.socket1.on('data', function (msg) {
                log.info('led1 data', msg);
            });

            this.socket1.on('error', function (error) {
                // log.error('led1 error', error);
            });

            this.socket1.on('close', () => {
                log.error('led1 下线了');
                setTimeout(() => {
                    this.socket1.connect(this.port, this.hostname1);
                }, 30 * 1000)
            });
        }

        if (settings.led2 !== '') {
            this.socket2 = new Socket();
            this.socket2.setEncoding('utf8');

            this.socket2.connect(this.port, this.hostname2, function () {
                log.info('led2 连接成功')
            });

            this.socket2.on('data', function (msg) {
                log.info('led2 data', msg);
            });

            this.socket2.on('error', function (error) {
                // log.error('led2 error', error);
            });

            this.socket2.on('close', () => {
                log.error('led2 下线了');
                setTimeout(() => {
                    this.socket2.connect(this.port, this.hostname1);
                }, 30 * 1000)
            });
        }
        // 加入心跳
        setInterval(() => {
            this.sendHlsk()
        }, 1000 * 60 * 10)
    }
}

const led = new LedImpl();
export default led;